package br.com.guardaroupavirtual.controller;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.hibernate.Session;
import org.hibernate.Transaction;

import br.com.guardaroupavirtual.facade.Facade;
import br.com.guardaroupavirtual.helper.Diretorios;
import br.com.guardaroupavirtual.helper.HibernateHelper;
import br.com.guardaroupavirtual.helper.NumberHelper;
import br.com.guardaroupavirtual.model.Categoria;
import br.com.guardaroupavirtual.model.Loja;
import br.com.guardaroupavirtual.model.LookEvento;
import br.com.guardaroupavirtual.model.Produto;
import br.com.guardaroupavirtual.model.Usuario;

@WebServlet(value = "/ProdutoController", name = "ProdutoController")
public class ProdutoController extends HttpServlet {
	private static final long serialVersionUID = 1L;

	private HttpServletRequest request;
	private HttpServletResponse response;

	private Facade fachada;

	private Session session;
	private Transaction transaction;

	private String cmd;
	private Map<String, Object> parametros;

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		this.request = request;
		this.response = response;

		cmd = request.getParameter("cmd");

		if (cmd == null || cmd.isEmpty()) {
			if (request.getSession().getAttribute("usuario") == null) {
				request.getRequestDispatcher(String.format(Diretorios.Usuario, "login.jsp")).forward(request,
						response);
			}			
			request.setAttribute("produtos", this.getProdutos());
			request.getRequestDispatcher(String.format(Diretorios.Produto, "lista_produto.jsp")).forward(
					request, response);
		} else {
			if (cmd.equalsIgnoreCase("cadastrar")) {
				if (request.getSession().getAttribute("usuario") == null) {
					request.getRequestDispatcher(String.format(Diretorios.Usuario, "login.jsp")).forward(request,
							response);
				}				
				request.setAttribute("lojas", this.getLojas());
				request.setAttribute("categorias", this.getcategorias());
				request.setAttribute("lookEventos", this.getLookEventos());
				request.getRequestDispatcher(String.format(Diretorios.Produto, "cadastra_produto.jsp"))
						.forward(request, response);
			}

			if (cmd.equalsIgnoreCase("alterar")) {
				if (request.getSession().getAttribute("usuario") == null) {
					request.getRequestDispatcher(String.format(Diretorios.Usuario, "login.jsp")).forward(request,
							response);
				}				
				session = HibernateHelper.getSessionFactory().openSession();
				fachada = Facade.getCurrentInstance();
				Produto produto = fachada.getProduto(session,Integer.parseInt(request.getParameter("id")));
				
				Usuario usuarioSessao = (Usuario) request.getSession().getAttribute("usuario");
				if(produto.getUsuario().getId() != usuarioSessao.getId()){
					request.setAttribute("produtos", this.getProdutos());
					request.setAttribute("mensagem", "O produto não encontrado!");
					request.getRequestDispatcher(String.format(Diretorios.Produto, "lista_produto.jsp")).forward(
							request, response);					
				}
				request.setAttribute("produto", produto);
				request.setAttribute("lojas", this.getLojas());
				request.setAttribute("categorias", this.getcategorias());
				request.setAttribute("lookEventos", this.getLookEventos());
				request.getRequestDispatcher(String.format(Diretorios.Produto, "altera_produto.jsp"))
						.forward(request, response);
			}

			if (cmd.equalsIgnoreCase("deletar")) {
				if (request.getSession().getAttribute("usuario") == null) {
					request.getRequestDispatcher(String.format(Diretorios.Usuario, "login.jsp")).forward(request,
							response);
				}				
				this.deletar(request, response);
			}
			
			if (cmd.equalsIgnoreCase("detalhe")) {
				session = HibernateHelper.getSessionFactory().openSession();
				fachada = Facade.getCurrentInstance();
				Produto produto = fachada.getProduto(session,Integer.parseInt(request.getParameter("id")));
				request.setAttribute("produto", produto);
				request.getRequestDispatcher(String.format(Diretorios.Produto, "detalhe_produto.jsp")).forward(request, response);				
			}

		}

	}

	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		this.request = request;
		this.response = response;

		parametros = this.getParametros();

		cmd = parametros.get("cmd").toString();
		
		if (cmd.equalsIgnoreCase("cadastrar")) {
			this.cadastrar();
		}
		if (cmd.equalsIgnoreCase("alterar")) {
			this.alterar();
		}
	}

	private List<Produto> getProdutos() {
		session = HibernateHelper.getSessionFactory().openSession();
		fachada = Facade.getCurrentInstance();
		return fachada.getProdutos(session);
	}

	private void cadastrar() throws ServletException, IOException {
		session = HibernateHelper.getSessionFactory().openSession();
		transaction = session.beginTransaction();

		try {
			fachada = Facade.getCurrentInstance();
			Produto produto = new Produto();
			produto.setNome(parametros.get("nome").toString());
			produto.setPreco(NumberHelper.stringToDecimalUS(parametros.get("preco").toString()));
			produto.setSexo(parametros.get("sexo").toString());
			produto.setMedida(parametros.get("medida").toString());
			Loja loja = fachada.getLoja(session,
					Integer.parseInt(parametros.get("lojaID").toString()));
			produto.setLoja(loja);
			Categoria categoria = fachada.getCategoria(session,
					Integer.parseInt(parametros.get("categoriaID").toString()));
			produto.setCategoria(categoria);
			LookEvento look = fachada.getLookEvento(session,
					Integer.parseInt(parametros.get("lookEventoID").toString()));
			produto.setLookEvento(look);
			FileItem fileItem = (FileItem) parametros.get("foto");
			if (fileItem != null) {
				String nomeArquivo = +new Date().getTime()+"_"+fileItem.getName();
				File uploaded = new File(this.getDiretorioUpload(nomeArquivo));
				fileItem.write(uploaded);
				produto.setFoto(this.getArquivoCarregado(nomeArquivo));
			}
			Usuario usuario = (Usuario) request.getSession().getAttribute("usuario");
			produto.setUsuario(usuario);
			fachada.cadastrarProduto(session, produto);
			transaction.commit();
			request.setAttribute("mensagem", "Registro inserido com sucesso!");
		} catch (Exception e) {
			request.setAttribute("mensagem",
					"Ocorreu um erro ao tentar inserir o registro!");
			transaction.rollback();
		}
		request.setAttribute("produtos", this.getProdutos());
		request.getRequestDispatcher(String.format(Diretorios.Produto, "lista_produto.jsp")).forward(
				request, response);
	}

	private void alterar() throws ServletException, IOException {
		session = HibernateHelper.getSessionFactory().openSession();
		transaction = session.beginTransaction();
		try {
			fachada = Facade.getCurrentInstance();
			Produto produto = fachada.getProduto(session, Integer.parseInt(parametros.get("id").toString()));
			produto.setNome(parametros.get("nome").toString());
			produto.setPreco(NumberHelper.stringToDecimalUS(parametros.get("preco").toString()));
			produto.setSexo(parametros.get("sexo").toString());
			produto.setMedida(parametros.get("medida").toString());
			Loja loja = fachada.getLoja(session,
					Integer.parseInt(parametros.get("lojaID").toString()));
			produto.setLoja(loja);
			Categoria categoria = fachada.getCategoria(session,
					Integer.parseInt(parametros.get("categoriaID").toString()));
			produto.setCategoria(categoria);
			LookEvento look = fachada.getLookEvento(session,
					Integer.parseInt(parametros.get("lookEventoID").toString()));
			produto.setLookEvento(look);
			FileItem fileItem = (FileItem) parametros.get("foto");
			if (fileItem != null) {
				String nomeArquivo = +new Date().getTime()+"_"+fileItem.getName();
				File uploaded = new File(this.getDiretorioUpload(nomeArquivo));
				fileItem.write(uploaded);
				produto.setFoto(this.getArquivoCarregado(nomeArquivo));
			}
			fachada.alterarProduto(session, produto);
			transaction.commit();
			request.setAttribute("mensagem", "Registro alterado com sucesso!");
		} catch (Exception e) {
			request.setAttribute("mensagem",
					"Ocorreu um erro ao tentar inserir o registro!");
			transaction.rollback();
		}
		request.setAttribute("produtos", this.getProdutos());
		request.getRequestDispatcher(String.format(Diretorios.Produto, "lista_produto.jsp")).forward(
				request, response);
	}

	
	private void deletar(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		session = HibernateHelper.getSessionFactory().openSession();
		transaction = session.beginTransaction();
		try {
			fachada = Facade.getCurrentInstance();
			Produto produto = fachada.getProduto(session, Integer.parseInt(request.getParameter("id")));
			Usuario usuarioSessao = (Usuario) request.getSession().getAttribute("usuario");
			if(produto.getUsuario().getId() != usuarioSessao.getId()){
				request.setAttribute("produtos", this.getProdutos());
				request.setAttribute("mensagem", "O produto não encontrado!");
				request.getRequestDispatcher(String.format(Diretorios.Produto, "lista_produto.jsp")).forward(
						request, response);					
			}			
			fachada.deletarProduto(session, produto);
			transaction.commit();
			request.setAttribute("mensagem", "Registro excluido com sucesso!");
		} catch (Exception e) {
			transaction.rollback();
			request.setAttribute("mensagem",
					"Ocorreu um erro ao tentar excluir o registro!");
		}
		request.setAttribute("produtos", this.getProdutos());
		request.getRequestDispatcher(String.format(Diretorios.Produto, "lista_produto.jsp")).forward(
				request, response);
	}

	private List<LookEvento> getLookEventos() {
		session = HibernateHelper.getSessionFactory().openSession();
		fachada = Facade.getCurrentInstance();
		return fachada.getLooksEvento(session);
	}

	private List<Categoria> getcategorias() {
		session = HibernateHelper.getSessionFactory().openSession();
		fachada = Facade.getCurrentInstance();
		return fachada.getCategorias(session);
	}

	private List<Loja> getLojas() {
		session = HibernateHelper.getSessionFactory().openSession();
		fachada = Facade.getCurrentInstance();
		return fachada.getLojas(session);
	}

	public Map<String, Object> getParametros() throws IOException {
		Map<String, Object> p = new HashMap<String, Object>();
		try {
			// Create a factory for disk-based file items
			DiskFileItemFactory factory = new DiskFileItemFactory();

			// Configure a repository (to ensure a secure temp location is used)
			ServletContext servletContext = this.getServletConfig()
					.getServletContext();
			File repository = (File) servletContext
					.getAttribute("javax.servlet.context.tempdir");
			factory.setRepository(repository);

			// Create a new file upload handler
			ServletFileUpload upload = new ServletFileUpload(factory);

			// Parse the request
			List<FileItem> items = upload.parseRequest(request);

			// Process the uploaded items
			Iterator<FileItem> iter = items.iterator();
			while (iter.hasNext()) {
			    FileItem item = iter.next();

			    if (item.isFormField()) {
			        p.put(item.getFieldName(), item.getString());
			    } else {
			    	if(item != null && !item.getName().isEmpty()){
			    		p.put(item.getFieldName(), item);
			    	}
			    }
			}			
			
		} catch (FileUploadException e) {
			e.printStackTrace();
		}
		return p;
	}
	
	private String getDiretorioUpload(String nomeArquivo) {
		String path = request.getServletContext().getRealPath("/Uploads").concat("/").concat(nomeArquivo);
		return path;
	}
	
	private String getArquivoCarregado(String nomeArquivo){
		return request.getContextPath().concat("/Uploads/").concat(nomeArquivo);
	}

}
